namespace Northwind.Web.App
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Runtime.Caching;
using Northwind.Domain.Core.Entities;
using NRepository.Core.Query;

public class EfCacheableInterceptor : IQueryInterceptor
{
    private static readonly object SyncObject = new object();
    private static readonly MemoryCache Cache = MemoryCache.Default;
    private static readonly IEnumerable<Type> _CacheableTypes = new[]
    {
        // Your entities here
        typeof(Customer)
    };

    public IQueryable<T> Query<T>(IQueryRepository repository, IQueryable<T> query, object additionalQueryData) where T : class
    {
        // It's not a cachable type
        if (!_CacheableTypes.Contains(typeof(T)))
            return query;

        var key = typeof(T).AssemblyQualifiedName;
        var items = Cache.Get(key);
        
        // Is it already cached
        if (items != null)
            return (IQueryable<T>)items;

        lock(SyncObject)
        {
            items = Cache.Get(key);
            if (items == null)
            {
                // if your not generating proxies you can use the following :
                // items = repository.GetEntities<T>(new AsNoTrackingQueryStrategy()).ToArray().AsQueryable();

                // Required so you don't put proxied entities into the cache (
                var dbContext = (DbContext)Activator.CreateInstance(repository.ObjectContext.GetType());
                dbContext.Configuration.ProxyCreationEnabled = false;
                items = dbContext.Set<T>().AsNoTracking().ToArray().AsQueryable();

                Cache.Add(key, items, new CacheItemPolicy());
 
            }

            return (IQueryable<T>)items;
        }
    }
}
}
